// use std::io;
// use std::cmp::Ordering;
// #[derive(Debug)]
// struct jiegou{
//     name:String,
//     age:u32,
// }
// impl jiegou {
//     fn age(&self) -> bool {
//         self.age >= 18
//     }
// }
// fn main() {
    // let num:u32 = 10;
    // println!("The value of num is {}", num);
    // let mut guess=String::new();
    // io::stdin().read_line(&mut guess).expect("Failed to read line");
    // let guess:u32 = guess.trim().parse().expect("Please type a number!");
    // println!("You guessed: {}", guess);
    // match guess.cmp(&num) {
    //     Ordering::Less => println!("Too small!"),
    //     Ordering::Greater => println!("Too big!"),
    //     Ordering::Equal => println!("You win!"),
    // }
    // loop {
    //     println!("test");
    //     break;
    // }
    // let mut x:u32=5; //let x = 5;
    // println!("The value of x is {}", x);
    // x=6;
    // println!("The value of x is {x}");
    // let y:&str="Hello";
    // println!("The value of y is {y}");
    // let str1: &str="Hello";
    // let str2 = String::from("Hello");
    // let mut str3 = String::new();
    // io::stdin().read_line(&mut str3).expect("Failed to read line");
    // println!("{str1}\n{str2}\n{str3}")
    // loop {
    //     println!("test");
    // }
    // let a=jiegou{
    //     name:String::from("test"),
    //     age:18,
    // };
    // println!("{} {}", a.name, a.age);
    // println!("{}", a.age());
    // println!("{}",str1.len());//获得字符串的长度
    // println!("{}",&str1[..]);//默认访问全部内容
    // println!("{}",&str1[1..3]);//访问指定内容
    // dbg!(&a);
// }
// struct jiegou{
//     name:String,
//     age:u32,
// }
// impl jiegou {
//     fn age(&self) -> bool {
//         self.age >= 18
//     }
//     fn other(&self,other:&jiegou) -> bool{
//         return self.age>other.age;
//     }
// }
// fn main() {
//     let j1=jiegou{
//         name:String::from("tss"),
//         age:18
//     };
//     let j2=jiegou{
//         name:String::from("tss"),
//         age:19
//     };
//     println!("{}",j1.other(&j2));
// }


// enum IpAddr {
//     V4(String),
//     V6(String),
// }
// enum Messege {
//     Quit, //没有任何关联数据
//     Move{x:i32,y:i32},
//     Write(String),
//     ChangeColour(i32,i32,i32),
// }
// enum Option<T> { //这个定义于标准库当中，使用时不需要：：
//     None,
//     Some(T),
// }
// fn main() {
//     let home=IpAddr::V4(String::from("127.0.1"));
//     let loopback=IpAddr::V6(String::from("::1"));

// }


// enum Coin {
//     Penny,
//     Nickel,
//     Dime,
//     Quarter,
// }
// enum Coin2 {
//     Penny(u32),
//     Nickel(u32),
// }
// fn value_in_cents(coin:Coin)->u16 {
//     match coin {
//         Coin::Penny =>{
//             println!("lucky penny");
//             1
//         },
//         Coin::Nickel =>5,
//         Coin::Dime =>10,
//         Coin::Quarter =>25,
//     }
// }
// fn if_let_test(coin2:Coin2) {
    
//     if let Coin2::Penny(number) = coin2 {
//         println!("this is the number:{}",number);
//     }
// }

// fn main() {
//     let penny=Coin::Penny;
//     value_in_cents(penny);


//     let shade=Coin2::Penny(55);
//     if_let_test(shade);
// }
// pub mod front_of_house;
// mod lib;
// use lib::front_of_house::hosting; //使用use关键字来导入模块
// fn main() {
//     lib::front_of_house::hosting::add_to_waitlist();
// }

// use std::io;
// use std::io::Write;
// use std::io::Read;

// use std::io::{self, Write, Read};

// pub use std::io::*; //使用*通配符来导入模块中的所有内容
// pub use crate::lib::front_of_house::hosting::add_to_waitlist; //使用crate关键字来导入当前crate中的模块

// fn main() {
//     let v:Vec<u32> = Vec::new();
//     let v2=vec![1,2,3]; //使用vec!宏来创建一个向量
//     let mut v3 = Vec::new();
//     let mut v4:Vec<u32> = vec![]; //创建vec的时候编译器需要获知向量的类型
//     v4.push(1);
//     v3.push(1);
//     v3.push(2);
//     println!("{}",&v2[0]);
//     // println!("{}",v2.get(0)); //使用get方法来获取向量中的元素,使用get提取，会返回option类型
//     //需要检查option类型是否为空，如果不为空再输出
//     //option枚举内含Some和None两种类型
//     //所以上面的编译会失败
//     for ve in &v2 {
//         println!("{}",ve);
//     }
//     /*
//      * 如果使用get方法获取向量中的元素，需要检查option类型是否为空，如果不为空再输出
//      * 可以使用两种方式使用get函数
//      * 一种是使用if let
//      * 第二种是使用match函数来匹配获得的类型为Option中的哪个类型
//      */
//     if let Some(third) = v2.get(2) {
//         println!("The third element is {}", third);
//     } else {
//         println!("The vector is empty");
//     }
//     match v2.get(2) {
//         Some(third) => println!("The third element is {}", third),
//         None => println!("The vector is empty"),
//     }
// }

// fn main() {
//     let mut s=String::new();
//     let data="hello world";
//     let s=data.to_string();
//     println!("{}",s);
//     let mut s2=String::from("hello");
//     s2.push_str(" world");
//     let s3=s+&s2;//s的所有权被转移，s3获得了所有权,s2因为只是引用，所以还继续拥有所有权
//     println!("{}",s3);
//     println!("{}",s2);
//     let s4=format!("{}-{}",s3,s2);//使用format!宏来创建一个新的字符串，这个字符串包含了s3和s2的内容，因为使用宏，所以不会转移所有权
    
//     // let s5=&s2+&s3; 这是无法编译的，因为新的对象s4需要获得到一个所有权String类型，但是s2和s3都是引用，所以无法获得所有权
//     // 但是s2和s3都是引用，所以无法获得所有权
//     // +号左边应该填写一个String类型，右边应该填写一个&str类型

//     let hello="你好";
//     println!("{}",hello.len());
//     let s6=&hello[..];
//     println!("{}",s6.len());
//     // 对字符串使用for循环输出
//     for c in s6.chars() {
//         println!("{}",c);
//     }
// }
// use std::collections::HashMap;
// fn main() {
//     let mut scores = HashMap::new();
//     scores.insert("Blue",10);
//     scores.insert("Yellow",50);
//     for (key,value) in &scores {
//         println!("{}:{}",key,value);
//     }
//     // 重复插入相同的key，会覆盖原来的value
//     scores.insert("Blue",20);
//     for (key,value) in &scores {
//         println!("{}:{}",key,value);
//     }
//     // 使用get方法来获取value,返回的是option枚举
//     let value = scores.get("Blue");
//     println!("{}:{}", "Blue", value.unwrap());
//     // 使用unwrap方法可以获取option枚举中的值，如果option枚举为空，则会panic
//     // 也可以使用if let来获取option枚举中的值
//     if let Some(value) = value {
//         println!("{}:{}", "Blue", value);
//     }
//     scores.entry("Blue").or_insert(50); //使用entry方法来获取value，如果value存在，则返回value，如果value不存在，则插入value
// }
/*
 * rust的异常通常是返回一个枚举，Result枚举，这个枚举有两个值，Ok和Err，Ok表示操作成功，Err表示操作失败
 * 处理这个枚举有几个方法
 * 1. 使用match来匹配枚举
 * 2. 使用unwrap来获取枚举中的值，如果枚举为空，则会panic
 * 3. 使用expect来获取枚举中的值，如果枚举为空，则会panic，并且会输出自定义的错误信息，自定义的错误信息需要被传入到expect方法中
 * 3. 使用if let来获取枚举中的值
 * 4. 使用?操作符来处理Result枚举，如果Result枚举为Err，则会返回Err，如果Result枚举为Ok，则会返回Ok中的值
 * 
 * ?操作符可以用于处理Result枚举和Option枚举
 * 在Result枚举中，如果含有OK，则返回OK中的值，如果含有Err，则返回Err
 * 在Option枚举中，如果含有Some，则返回Some中的值，如果含有None，则返回None
 * 
 * 其中使用unwrap,expect,?来处理Result枚举比较方便和广泛
 * 
 * 
 * rust也可以通过panic!()来抛出异常，但是panic!()会终止程序的运行，所以一般不使用panic!()来处理异常
 * 类似于java的抛出异常
*/
// fn main() ->Result<(),std::io::Error> {
//     // panic!("Hello, world!"); //类似于java中的throw new Exception("Hello, world!");
//    let mut username=String::new();
//    use std::fs::File;
//    use std::io::Read;
//    File::open("hello.txt")?.read_to_string(&mut username)?;
//    println!("username:{}",username);
//    File::open("hello.txt").unwrap();
//    File::open("hello.txt").expect("hello.txt should be included in this project");
//    Ok(())
// }

// fn test() ->Result<&'static str,std::io::Error> {
//     if(1>0){Ok("hello")} else {
//         Err(std::io::Error::new())
//     }    
// }
// fn test2() ->Result<String,std::io::Error> {
//     if(1>0){Ok(String::from("hello"))} else {
//         Err(std::io::Error::new())
//     }  
// }

// struct Point<T> {
//     id:T,
//     phone_number:T,
// }
// impl<T:std::fmt::Display> Point<T> { //因为T没有实现Display trait，所以需要使用泛型T来实现Display trait，否则如果要显示的话会无法通过编译
//     fn display(&self) {
//         println!("id:{}",self.id);
//         println!("phone_number:{}",self.phone_number);
//     }
// }

// struct Point2<T,U> {
//     id:T,
//     name:U,
// }

// fn main() {
//     let p1=Point{id:1,phone_number:123456789};
//     p1.display();
//     let p2=Point2{id:1,name:String::from("hello")};
// }

// pub struct NewArticle{
//     pub  headline: String,
//     pub  location: String,
//     pub  author: String,
//     pub  content: String
// }
// pub trait Summary {
//     fn summarize(&self) -> String;
//     fn summarize_author2(&self) -> String{ //如果已经在trait中定义了方法，那么在实现trait的时候就不需要再定义这个方法了
//         "this is a test".to_string()
//     }
// }
// impl Summary for NewArticle {
//     fn summarize(&self) -> String {
//         format!("{}, by {} ({})", self.headline, self.author, self.location)
//     }
    
// }


// fn main() {
//     let article = NewArticle {
//         headline:"Hello".to_string(),
//         location:"world".to_string(),
//         author:"me".to_string(),
//         content:"hello world".to_string()
//     };
//     println!("{}",article.summarize());
//     println!("{}",article.summarize_author2());
//     notify(&article);
//     let s2=return_sum();
//     notify(&s2);
// }
// fn notify(item:&impl Summary) {
//     println!("Breaking news! {}",item.summarize());
//     println!("Breaking news! {}",item.summarize_author2());
// }

// fn return_sum() ->impl Summary {
//     NewArticle {
//         headline:"Hello".to_string(),
//         location:"world".to_string(),
//         author:"me".to_string(),
//         content:"hello world".to_string()
//     }
// }


// fn main() {
//     let x= 5;
//     let y = &x;
//     println!("x is {}, y is {}", x, y);
//     let s2=Point{
//         x: &x,
//         y: &x,
//         name: "hello",
//     };
//     println!("{}",s2.sum());
// }

// fn bigger<'a>(a: &'a i32, b: &'a i32) -> &'a i32  {
//     if a>b {
//         a
//     } else {
//         b
//     }
    
// }
// // 错误示范
// // fn bigger(a: & i32, b: & i32) -> & i32  {
// //     if a>b {
// //         a
// //     } else {
// //         b
// //     } 
// // }
// struct Point<'a> {
//     x: &'a i32,
//     y: &'a i32,
//     name: &'a str,
// }
// trait Summary<'a> {
//     fn sum(&self) -> &str;
// }
// impl<'a> Summary<'a> for Point<'a> {
//     fn sum(&self) -> &str {
//         self.name
//     }
// }


// #[derive(Debug, PartialEq,Copy,Clone)]
// enum ShirtColor {
//     Red,
//     Blue,
// }
// struct Inventory {
//     shirts: Vec<ShirtColor>,
// }
// impl Inventory {
//     fn giveaway(&self,user_preference:Option<ShirtColor>) ->ShirtColor {
//         user_preference.unwrap_or_else(|| self.most_stocked())
//     }
//     fn most_stocked(&self) -> ShirtColor {
//         let mut num_red = 0;
//         let mut num_blue = 0;
//         for color in &self.shirts {
//             match color {
//                 ShirtColor::Red => num_red += 1,
//                 ShirtColor::Blue => num_blue += 1,
//             }
//         }
//         if num_red > num_blue {
//             ShirtColor::Red
//         } else {
//             ShirtColor::Blue
//         }
//     }
// }
// fn main() {
//     let store = Inventory {
//         shirts: vec![ShirtColor::Blue, ShirtColor::Red, ShirtColor::Blue],
//     };
//     let user_pref1 = Some(ShirtColor::Red);
//     let giveaway1 = store.giveaway(user_pref1);
//     println!(
//         "the user with preference {:?} gets {:?}",
//         user_pref1, giveaway1
//     );
// }



// fn main() {
//     let mut x: i32=1;
//     let y: i32=2;
//     // 对于闭包，“->”和“{}”是可选的，不写也没关系
//     //大括号可以在里面执行多条语句，但是返回值必须是最后一个语句的值
//     // let add = |x,y| x+y;
//     let add2 = |x: i32,y: i32| x+y;
//     let add3 = |x: i32,y: i32| -> i32 {x+y};
//     // let add4 = |x,y| -> i32 {x+y};
//     let add5 = |x| x;
//     let s = add5(5);
//     let s2=add5(6); //因为类型一样，所以不会报错
//     // let b = add5(String::from("hello"));
//     //对于add5闭包，我们并没有指定接受的类型
//     //所以编译器会自动推断出类型
//     //如果我们第一次使用add5时传入的是i32类型，但是第二次传入的是String类型
//     //那么编译器将无法推断出类型，就会报错
//     let add6=|| x+1;
//     println!("{}",add6());
//     //如果需要在闭包中修改外部变量，需要使用mut关键字
//     let mut add7=|| x+=1;
//     add7();
//     println!("{}",x);
//     let mut add8=move |x| x+1;//使用move关键字，将形参x的所有权转移到闭包中
//     println!("{}",add8(5));
//     let mut add9=move || x+=1;//将外部变量x的所有权转移到闭包中
// }




// fn main() {
//     let v1=vec![1,2,3,4,5]; //定义一个vector
//     let v1_iter = v1.iter(); //从v1获得一个迭代器，v1的所有权被转移到了v1_iter中
//     for val in v1_iter {
//         println!("{}",val);
//     }
//     let v2 = vec![1,2,3,4,5];
//     let v2_iter = v2.iter();
//     let total:&i32= &v2_iter.sum(); //使用sum方法，将迭代器中的元素相加
//     println!("总和为{}",total);
//     let map_test = v2.iter().clone().map(|x| x+1); //使用map方法，将迭代器中的元素加1
//     let map_test2 = map_test.clone();
//     for val in map_test {
//         println!("{}",val);
//     }
//     let v3:Vec<i32> = map_test2.collect(); //使用collect方法，将迭代器中的元素收集到一个新的vector中
// }
// pub trait Iterator {
//     type Item; //定义一个Item类型，用于迭代器中的元素类型
//     fn next(&mut self) -> Option<Self::Item>; //定义一个next方法，用于获取下一个元素
        
    
// }

// fn main() {
//     // 实现无限嵌套
//     let list = List::Cons(1,Box::new(List::Cons(2,Box::new(List::Cons(3,Box::new(List::Nil))))));;
// }

// enum List {
//     // 不能直接在Cons中写入List类型
//     // Cons(i32,List),因为这样子编译器无法确定枚举所占用的内存大小
//     // 所以需要使用Box，box是一个指针，可以指向任意大小的内存，但是指向堆内存的指针的大小是确定的
//     Cons(i32,Box<List>),
//     Nil,
// }


// fn main() {
//     let x = 5;
//     let y = &x;
//     let y = Box::new(x.clone()); //可以将x克隆一个在堆内存中，然后将y指向这个堆内存
//     assert_eq!(5, x);
//     assert_eq!(5, *y);
//     // assert_eq!(5, y); 不允许比较数字的引用和数字本身，必须要使用解引用
//     println!("{}",y);
    
// }

// // 接下来我们定义一个自己的Box
// struct Mybox<T>(T);
// impl<T> Mybox<T> {
//     fn new(x: T) -> Mybox<T> {
//         Mybox(x)
//     }
// }
// // 我们需要实现Deref trait，这样我们就可以使用*操作符来解引用Mybox<T>
// use std::ops::Deref;
// impl<T> Deref for Mybox<T> {
//     type Target = T;
//     fn deref(&self) -> &Self::Target {
//         &self.0
//     }
// }

// drop trait不需要手动引入，因为它是一个内置的trait，已经包含在了prelude中
// struct CustomSmartPointer{
//     data: String,
// }
// impl Drop for CustomSmartPointer {
//     fn drop(&mut self) {
//         println!("Dropping CustomSmartPointer with data: {}", self.data);
//     }
// }
// fn main() {
//     let c = CustomSmartPointer {
//         data: String::from("my stuff"),
//     };
//     let d = CustomSmartPointer {
//         data: String::from("other stuff"),
//     };
//     println!("CustomSmartPointer created.");
//     drop(c);
// }


// use std::rc::{Rc,Weak};
// enum List{
//     Cons(i32,Rc<List>),
//     Nil,
// }
// fn main() {
//     // 实现无限嵌套
//     let a = Rc::new(List::Cons(1,Rc::new(List::Cons(2,Rc::new(List::Cons(3,Rc::new(List::Nil)))))));
//     let b = List::Cons(1,Rc::clone(&a));
//     let c = List::Cons(1,Rc::clone(&a));
//     let strong = Rc::new(5);
//     let weak = Rc::downgrade(&strong);
//     // weak是strong的弱引用，此时strong还可以使用，并且计数值为1
//     let strong2 = weak.upgrade(); // weak升级为strong，此时strong的计数值为2
// }

// use std::thread;
// use std::time::Duration;
// fn main() {
//     let mut  v=10;
//     let handle = thread::spawn(move || {
//         for i in 0..10 {
//             println!("hi number {} from the spawned thread!", i);
//             println!("v:{v}");
//             v+=1;
//             thread::sleep(Duration::from_millis(1));
//         }
//     });
    
//     for i in 0..5 {
//         println!("hi number {} from the main thread!", i);
//         thread::sleep(Duration::from_millis(1));
//     }
//     handle.join().unwrap(); // 会阻塞等待handle线程全部执行完毕
//     // 如果不阻塞的话。程序虽然也会同时运行着两个输出
//     // 但是程序会在main方法的输出结束完就会关闭，而不会等待handle线程的输出执行完毕结束
//     // 因此我们需要阻塞进程等待进程执行完毕
// }


// use std::thread;
// use std::sync::mpsc;
// fn main() {
//     let (sender, receiver) = mpsc::channel();
    
//     thread::spawn(move || {
//         let val = String::from("hi");
//         println!("val is {val}");
//         sender.send(val).unwrap();
//     });
//     let received = receiver.recv().unwrap(); //这个方法会发生阻塞，直到接收到消息为止
//     // let received = receiver.try_recv(); //这个方法不会发生阻塞，如果接收不到消息就会返回一个错误
//     println!("Got: {received}");
// }

// use std::thread;
// use std::sync::mpsc;
// use std::time::Duration;
// fn main() {
//     let (sender, receiver) = mpsc::channel();
    
//     thread::spawn(move || {
//         let vals = vec![
//             String::from("hi"),
//             String::from("from"),
//             String::from("the"),
//             String::from("thread"),
//         ];

//         for val in vals {
//             sender.send(val).unwrap();
//             thread::sleep(Duration::from_secs(1));
//         }
//     });
//     for received in receiver {
//         println!("Got: {received}");
//     }
// }


// use std::thread;
// use std::sync::mpsc;
// use std::time::Duration;
// fn main() {
//     let (sender, receiver) = mpsc::channel();
//     let sender2 = sender.clone();
//     let sender3 = sender.clone();
//     thread::spawn(move || {
//         let vals = vec![
//             String::from("hi"),
//             String::from("from"),
//             String::from("the"),
//             String::from("thread"),
//         ];

//         for val in vals {
//             sender2.send(val).unwrap();
//             thread::sleep(Duration::from_secs(1));
//         }
//     });
//     thread::spawn(move || {
//         let vals = vec![
//             String::from("hi2"),
//             String::from("from2"),
//             String::from("the2"),
//             String::from("thread2"),
//         ];

//         for val in vals {
//             sender3.send(val).unwrap();
//             thread::sleep(Duration::from_secs(1));
//         }
//     });
//     for received in receiver {
//         println!("Got: {received}");
//     }
// }


// use std::sync::{Mutex, Arc};
// use std::thread;
// fn main() {
//     let counter = Arc::new(Mutex::new(0));
//     let mut handlers = vec![]; // 创建一个存放线程句柄的向量
//     for _ in 0..10 {
//         let counter = Arc::clone(&counter);
//         let handler = thread::spawn(move || {
//             let mut num = counter.lock().unwrap();
//             *num += 1;
//         });
//         handlers.push(handler); // 将线程句柄存放到向量中
//     }
//     for handler in handlers {
//         handler.join().unwrap(); // 等待所有线程执行完毕
//     }
//     // 只有获得了锁才能对共享资源进行操作，因此我们需要使用lock方法来获取锁
//     // lock方法会返回一个Result类型，如果获取到了锁就会返回Ok，否则就会返回Err
//     // 因此我们需要使用unwrap方法来获取锁，如果获取不到锁就会panic
//     // 如果我们想要在获取不到锁的时候不panic，我们可以使用unwrap_or_else方法来获取锁
//     // 只有在获得了锁之后，才能查看和修改
//     // 在没有获得互斥锁之前，无法执行查看和修改操作
//     println!("Result: {}", *counter.lock().unwrap());// 获取最终结果
// }

// use trpl::{Html, Response};
// use std::time::Duration;
// async fn page_title(url: &str) ->Option<String> {
//     let response = trpl::get(url).await;
//     let response_text = response.text().await;
//     Html::parse(&response_text)
//         .select_first("title")
//         .map(|title_element| title_element.inner_html())
    
// }

// async fn test1() {
//     println!("test1 is begining");
//     trpl::sleep(Duration::from_secs(2)).await;
//     println!("test1 is ending");
// }

// async fn test2() {
//     println!("test2 is begining");
//     trpl::sleep(Duration::from_secs(1)).await;
//     println!("test2 is ending");
// }



// fn main() {
//     trpl::run(async {
//       trpl::join(test1(), test2()).await;
//     }
//     );
// }


// 一下是错误的示范，因为没有用到并发，需要等到所有消息发送完之后才会执行接受操作
// use trpl::{Html, Response};
// use std::time::Duration;
// fn main() {
//     trpl::run(async {
//         let (sender, mut  receiver) = trpl::channel();
//         // sender.send("this is a message").unwrap();

//         // let received = receiver.recv().await.unwrap();
//         // println!("Got: {received}");

//         let values = vec![
//             "hi","from","the","channel"
//         ];
//         for value in values {
//             sender.send(value).unwrap();
//             trpl::sleep(Duration::from_secs(1)).await;
//         }
//         while let Some(value) = receiver.recv().await {
//             println!("Got: {value}");
//         }
//     })
// }


// use trpl::{Html, Response};
// use std::time::Duration;
// fn main() {
//     trpl::run(async {
//         let (sender, mut  receiver) = trpl::channel();
//         // sender.send("this is a message").unwrap();

//         // let received = receiver.recv().await.unwrap();
//         // println!("Got: {received}");
//         let sent = async{
//             let values = vec![
//             "hi","from","the","channel"
//         ];
//         for value in values {
//             sender.send(value).unwrap();
//             trpl::sleep(Duration::from_secs(1)).await;
//         }
//         };
//         let rece = async{
//             while let Some(value) = receiver.recv().await {
//                 println!("Got: {value}");
//             }
//         };
//         let handle3 = trpl::spawn_task(async{
//             println!("handle3 is begining");
//             trpl::sleep(Duration::from_secs(1)).await;
//             println!("handle3 is ending");
//         }
//         );
//         // trpl::join(sent, rece).await;
//         trpl::join!(sent, rece, handle3);
        
//     })
// }

// use tokio::*;
// use std::time::Duration;
// async fn test1() -> i32{
//     println!("test1 is begining");
//     tokio::time::sleep(Duration::from_secs(1)).await;
//     println!("test1 is ending");
//     return 1;
// }
// async fn test2() -> i32{
//     println!("test2 is begining");
//     tokio::time::sleep(Duration::from_secs(1)).await;
//     println!("test2 is ending");
//     return 2;
// }
// async fn test3() -> i32{
//     println!("test3 is begining");
//     tokio::time::sleep(Duration::from_secs(1)).await;
//     println!("test3 is ending");
//     return 3;
// }

// // 只有在使用了#[tokio::main]标注了main方法中，main方法才能使用async关键字
// // 否则main方法是不能直接使用async的
// #[tokio::main]
// async fn main() {
//     // tokio::join!(test1(), test2(), test3());如果我们的异步方法没有返回值可以或者我们不需要返回值可以这么写
//     let(a,b,c) = tokio::join!(test1(), test2(), test3());
//     println!("a:{},b:{},c:{}",a,b,c);

//     //或者我们可以在main方法中定义一个异步task，然后在main方法中调用这个异步函数
//     let handle1 = tokio::spawn(async {
//         println!("handle1 is begining");
//         tokio::time::sleep(Duration::from_secs(1)).await;
//         println!("handle1 is ending");
//         return 1;
//     });
//     let handle2 = tokio::spawn(async {
//         println!("handle2 is begining");
//         tokio::time::sleep(Duration::from_secs(1)).await;
//         println!("handle2 is ending");
//         return 2;
//     });

//     //我们在使用tokio::spawn方法创建异步任务时，它会返回一个JoinHandle类型，这个类型可以用来获取异步任务的返回值
//     //如果我们要取出异步任务的返回值，需要使用unwrap方法，如果异步任务没有返回值，那么unwrap方法会返回None
//     let (a,b) = tokio::join!(handle1, handle2);
//     println!("a:{},b:{}",a.unwrap(),b.unwrap());
// }

// //如果不使用#[tokio::main]标注main方法
// //我们可以手动创建tokio的运行时环境，然后在这个运行时环境中执行我们的异步函数
// // use tokio::runtime::Runtime;
// // fn main() {
// //     let rt = Runtime::new().unwrap();
// //     rt.block_on(async {
// //         tokio::join!(test1(), test2(), test3());
// //     })
// // }

// fn main() {
//     let mut num = 5;
//     // 获得裸指针
//     let r1 = &mut num as *mut i32;
//     let r2 = &num as *const i32;
//     println!("{:?}", r1); //输出内存地址
//     // println!("{:?}", *r1); //报错
//     unsafe {
//         println!("{:?}", r1); //输出内存地址
//         println!("{:?}", r2); //输出内存地址
//         println!("{:?}", *r1); //输出内存地址中的值(解引用)
//     }
// }

// unsafe fn dangerous() {
//     println!("this is a dangerous function");
// }

// fn main() {
//     // dangerous();// 错误
//     unsafe {
//         dangerous();
//     }
// }

// #[no_mangle] // 告诉编译器这个函数的名称不能被更改，这样子就能够编译成动态库并从C语言中链接
// pub extern "C" fn call_from_c() {
//     println!("Just called a Rust function from C!");
// }

// fn main() {
    
// }

// unsafe trait Foo {
//     // methods go here
// }
// unsafe impl Foo for i32 {
//     // method implementations go here
// }

// fn main() {
    
// }

// struct Point {
//     x: i32,
//     y: i32,
// }
// impl Point {
//     fn pri(&self) {
//         println!("{} {}", self.x, self.y);
//     }
// }
// trait PointTrait {
//     fn pri(&self) {}
// }
// impl PointTrait for Point {
//     fn pri(&self) {
//         println!("PointTrait{} {}", self.x, self.y);
//     }
// }

// fn main() {
//     let p = Point { x: 1, y: 2 };
//     p.pri(); //使用默认的impl
//     PointTrait::pri(&p); // 使用trait的impl
//     <Point as PointTrait>::pri(&p); // 使用trait的impl
// }

// struct Point {
//     x: i32,
//     y: i32,
// }
// trait PointTrait {
//     type T;
//     fn add(&self) -> Option<Self::T>;
// }
// impl PointTrait for Point {
//     type T = i32;
//     fn add(&self) -> Option<Self::T> {
//         Some(self.x + self.y)
//     }
// }
// fn main() {
//     let p = Point { x: 1, y: 2 };
//     let r = p.add().unwrap();
//     println!("{}", r);
// }


// fn add_one(x: i32) -> i32 {
//     x + 1
// }
// fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
//     f(arg) + f(arg)
// }
// fn a() -> fn() ->i32 {
//     fn b() -> i32 {
//         5
//     };
//     return b;
// }
// fn main() {
//     let answer = do_twice(add_one, 5);
//     println!("The answer is: {}", answer);
// }


fn return_trait() ->Box<dyn Fn() -> i32> {
    let a =||  9 ;
    return Box::new(a);
}
fn main() {
    let a = return_trait();
    println!("{}", a());
}